1 module hip.game2d.threepatch; 2 3 public import hip.api.renderer.texture; 4 public import hip.game2d.sprite; 5 import hip.api; 6 import hip.game2d.renderer_data; 7 8 enum ThreePatchOrientation 9 { 10 horizontal, 11 vertical, 12 inferred 13 } 14 15 16 class ThreePatch 17 { 18 int x, y; 19 int width, height; 20 HipSpriteVertex[4*3] vertices; 21 HipSprite[3] sprites; 22 ThreePatchOrientation orientation; 23 ThreePatchOrientation inferredOrientation = ThreePatchOrientation.inferred; 24 25 this(string texturePath, ThreePatchOrientation orientation = ThreePatchOrientation.inferred) 26 { 27 this(HipAssetManager.loadTexture(texturePath).awaitAs!IHipTexture, width, height, orientation); 28 } 29 this(IHipTexture texture, int width, int height, ThreePatchOrientation orientation = ThreePatchOrientation.inferred) 30 { 31 for(int i = 0; i < 3; i++) 32 sprites[i] = new HipSprite(texture); 33 34 this.orientation = orientation; 35 this.inferredOrientation = infer(width, height); 36 setSize(width, height); 37 } 38 pragma(inline) ThreePatchOrientation getOrientation() 39 { 40 if(orientation == ThreePatchOrientation.inferred) 41 return inferredOrientation; 42 return orientation; 43 } 44 void setOrientation(ThreePatchOrientation ori = ThreePatchOrientation.horizontal) 45 { 46 if(orientation == ThreePatchOrientation.inferred) 47 return setOrientation(inferredOrientation); 48 if(ori != orientation) 49 { 50 orientation = ori; 51 build(); 52 } 53 } 54 55 void setSize(int width, int height) 56 { 57 this.width = width; 58 this.height = height; 59 60 61 if(getOrientation == ThreePatchOrientation.horizontal) 62 { 63 float rw = sprites[0].getTextureWidth/3; 64 sprites[0].setRegion(0, 0, rw, 1.0); 65 sprites[1].setRegion(rw, 0, rw*2, 1.0); 66 sprites[2].setRegion(rw*2, 0, rw*3, 1.0); 67 } 68 else 69 { 70 float rh = sprites[0].getTextureHeight/3; 71 sprites[0].setRegion(0, 0, rh, 1.0); 72 sprites[1].setRegion(rh, 0, rh*2, 1.0); 73 sprites[2].setRegion(rh*2, 0, rh*3, 1.0); 74 } 75 build(); 76 } 77 78 protected void updatePosition() 79 { 80 if(getOrientation == ThreePatchOrientation.horizontal) 81 { 82 int spWidth = sprites[0].width; 83 sprites[0].setPosition(x, y); 84 sprites[1].setPosition(x+spWidth, y); 85 sprites[2].setPosition(x+width-(spWidth*2), y); 86 } 87 else 88 { 89 int spHeight = sprites[0].height; 90 sprites[0].setPosition(x, y); 91 sprites[1].setPosition(x, y+spHeight); 92 sprites[2].setPosition(x, y+height-(spHeight*2)); 93 } 94 } 95 96 void build() 97 { 98 if(getOrientation == ThreePatchOrientation.horizontal) 99 { 100 int spWidth = sprites[0].width; 101 float xScalingFactor = width-(spWidth*2); 102 if(spWidth != 0) 103 xScalingFactor/= spWidth; 104 else 105 xScalingFactor = 0; 106 107 sprites[0].setPosition(x, y); 108 sprites[1].setPosition(x+spWidth, y); 109 sprites[1].setScale(xScalingFactor, 1); 110 sprites[2].setPosition(x+width-(spWidth*2), y); 111 } 112 else 113 { 114 int spHeight = sprites[0].height; 115 float yScalingFactor = height-(spHeight*2); 116 if(spHeight != 0) 117 yScalingFactor/= spHeight; 118 else 119 yScalingFactor = 0; 120 121 sprites[0].setPosition(x, y); 122 sprites[1].setPosition(x, y+spHeight); 123 sprites[1].setScale(1, yScalingFactor); 124 sprites[2].setPosition(x, y+height-(spHeight*2)); 125 } 126 } 127 128 129 130 void setPosition(int x, int y) 131 { 132 updatePosition(); 133 } 134 135 ref HipSpriteVertex[4*3] getVertices(){return vertices;} 136 137 } 138 139 private ThreePatchOrientation infer(int width, int height){return width > height ? ThreePatchOrientation.horizontal : ThreePatchOrientation.vertical;} 140 141 142 /** 143 * 0 1 2 144 * ________ 145 * |________| 146 * 147 * 148 * ___ 149 * | | 0 150 * | | 1 151 * |___| 2 152 */